home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / m6502 / 6502dasm.c next >
C/C++ Source or Header  |  2000-05-18  |  36KB  |  969 lines

  1. /*****************************************************************************
  2.  *
  3.  *    6502dasm.c
  4.  *    6502/65c02/6510 disassembler
  5.  *
  6.  *    Copyright (c) 1998 Juergen Buchmueller, all rights reserved.
  7.  *
  8.  *    - This source code is released as freeware for non-commercial purposes.
  9.  *    - You are free to use and redistribute this code in modified or
  10.  *      unmodified form, provided you list me in the credits.
  11.  *    - If you modify this source code, you must add a notice to each modified
  12.  *      source file that it has been changed.  If you're a nice person, you
  13.  *      will clearly mark each change too.  :)
  14.  *    - If you wish to use this for commercial purposes, please contact me at
  15.  *      pullmoll@t-online.de
  16.  *    - The author of this copywritten work reserves the right to change the
  17.  *       terms of its usage and license at any time, including retroactively
  18.  *     - This entire notice must remain in the source code.
  19.  *
  20.  *****************************************************************************/
  21. /* 2. February 2000 PeT added support for 65sc02 subtype */
  22. /* 2. February 2000 PeT added support for 65ce02 variant */
  23. /* 3. February 2000 PeT bbr bbs displayment */
  24. /* 4. February 2000 PeT ply inw dew */
  25. /* 4. February 2000 PeT fixed relative word operand */
  26. /* 9. May 2000 PeT added m4510 */
  27.  
  28. #include <stdio.h>
  29. #ifdef MAME_DEBUG
  30. #include "driver.h"
  31. #include "mamedbg.h"
  32. #include "m6502.h"
  33. #if (HAS_M65CE02)
  34. #include "m65ce02.h"
  35. #endif
  36. #if (HAS_M6509)
  37. #include "m6509.h"
  38. #endif
  39. #if (HAS_M4510)
  40. #include "m4510.h"
  41. #endif
  42.  
  43. #define OPCODE(A)  cpu_readop(A)
  44. #define ARGBYTE(A) cpu_readop_arg(A)
  45. #define ARGWORD(A) cpu_readop_arg(A)+(cpu_readop_arg((A+1) & 0xffff) << 8)
  46.  
  47. #define RDMEM(A)   cpu_readmem16(A)
  48.  
  49. enum addr_mode {
  50.     non,   /* no additional arguments */
  51.     imp,   /* implicit */
  52.     acc,   /* accumulator */
  53.     imm,   /* immediate */
  54.     iw2,   /* immediate word (65ce02) */
  55.     adr,   /* absolute address (jmp,jsr) */
  56.     aba,   /* absolute */
  57.     zpg,   /* zero page */
  58.     zpx,   /* zero page + X */
  59.     zpy,   /* zero page + Y */
  60.     zpi,   /* zero page indirect (65c02) */
  61.     zpb,   /* zero page and branch (65c02 bbr,bbs) */
  62.     abx,   /* absolute + X */
  63.     aby,   /* absolute + Y */
  64.     rel,   /* relative */
  65.     rw2,   /* relative word (65cs02, 65ce02) */
  66.     idx,   /* zero page pre indexed */
  67.     idy,   /* zero page post indexed */
  68.     idz,   /* zero page post indexed (65ce02) */
  69.     isy,   /* zero page pre indexed sp and post indexed y (65ce02) */
  70.     ind,   /* indirect (jmp) */
  71.     iax    /* indirect + X (65c02 jmp) */
  72. };
  73.  
  74. enum opcodes {
  75.     adc,  and, asl,  bcc,  bcs,  beq,  bit,  bmi,
  76.     bne,  bpl, brk,  bvc,  bvs,  clc,  cld,  cli,
  77.     clv,  cmp, cpx,  cpy,  dec,  dex,  dey,  eor,
  78.     inc,  inx, iny,  jmp,  jsr,  lda,  ldx,  ldy,
  79.     lsr,  nop, ora,  pha,  php,  pla,  plp,  rol,
  80.     ror,  rti, rts,  sbc,  sec,  sed,  sei,  sta,
  81.     stx,  sty, tax,  tay,  tsx,  txa,  txs,  tya,
  82.     ill,
  83. /* 65c02 (only) mnemonics */
  84.     bbr,  bbs, bra,  rmb,  smb,  stz,  trb,  tsb,
  85. /* 65sc02 (only) mnemonics */
  86.     bsr,
  87. /* 6510 + 65c02 mnemonics */
  88.     anc,  asr, ast,  arr,  asx,  axa,  dcp,  dea,
  89.     dop,  ina, isc,  lax,  phx,  phy,  plx,  ply,
  90.     rla,  rra, sax,  slo,  sre,  sah,  say,  ssh,
  91.     sxh,  syh, top,  oal,  kil,
  92. /* 65ce02 mnemonics */
  93.     cle,  see,    map,
  94.     tab,  tba,    taz,  tza, tys, tsy,
  95.     ldz,  stz2/* real register store */,
  96.     dez,  inz,    cpz,  phz,    plz,
  97.     neg,  asr2/* arithmetic shift right */,
  98.     asw,  row,    dew,  inw,    phw
  99. };
  100.  
  101.  
  102. static const char *token[]=
  103. {
  104.     "adc", "and", "asl", "bcc", "bcs", "beq", "bit", "bmi",
  105.     "bne", "bpl", "brk", "bvc", "bvs", "clc", "cld", "cli",
  106.     "clv", "cmp", "cpx", "cpy", "dec", "dex", "dey", "eor",
  107.     "inc", "inx", "iny", "jmp", "jsr", "lda", "ldx", "ldy",
  108.     "lsr", "nop", "ora", "pha", "php", "pla", "plp", "rol",
  109.     "ror", "rti", "rts", "sbc", "sec", "sed", "sei", "sta",
  110.     "stx", "sty", "tax", "tay", "tsx", "txa", "txs", "tya",
  111.     "ill",
  112. /* 65c02 mnemonics */
  113.     "bbr", "bbs", "bra", "rmb", "smb", "stz", "trb", "tsb",
  114. /* 65sc02 (only) mnemonics */
  115.     "bsr",
  116. /* 6510 mnemonics */
  117.     "anc", "asr", "ast", "arr", "asx", "axa", "dcp", "dea",
  118.     "dop", "ina", "isc", "lax", "phx", "phy", "plx", "ply",
  119.     "rla", "rra", "sax", "slo", "sre", "sah", "say", "ssh",
  120.     "sxh", "syh", "top", "oal", "kil",
  121.     /* 65ce02 mnemonics */
  122.     "cle", "see", "map",
  123.     "tab", "tba", "taz", "tza", "tys", "tsy",
  124.     "ldz", "stz",
  125.     "dez", "inz", "cpz", "phz", "plz",
  126.     "neg", "asr",
  127.     "asw", "row", "dew", "inw", "phw"
  128. };
  129.  
  130. /* Some really short names for the EA access modes */
  131. #define VAL EA_VALUE
  132. #define JMP EA_ABS_PC
  133. #define BRA EA_REL_PC
  134. #define MRD EA_MEM_RD
  135. #define MWR EA_MEM_WR
  136. #define MRW EA_MEM_RDWR
  137. #define ZRD EA_ZPG_RD
  138. #define ZWR EA_ZPG_WR
  139. #define ZRW EA_ZPG_RDWR
  140.  
  141. /* words */
  142. #define MRD2 EA_MEM_RD
  143. #define MRW2 EA_MEM_RDWR
  144. #define ZRD2 EA_ZPG_RD
  145. #define ZRW2 EA_ZPG_RDWR
  146.  
  147. static const UINT8 op6502[256][3] = {
  148.     {brk,imm,VAL},{ora,idx,MRD},{ill,non,0    },{ill,non,0 },/* 00 */
  149.     {ill,non,0    },{ora,zpg,ZRD},{asl,zpg,ZRW},{ill,non,0 },
  150.     {php,imp,0    },{ora,imm,VAL},{asl,acc,0    },{ill,non,0 },
  151.     {ill,non,0    },{ora,aba,MRD},{asl,aba,MRW},{ill,non,0 },
  152.     {bpl,rel,BRA},{ora,idy,MRD},{ill,non,0    },{ill,non,0 },/* 10 */
  153.     {ill,non,0    },{ora,zpx,ZRD},{asl,zpx,ZRW},{ill,non,0 },
  154.     {clc,imp,0    },{ora,aby,MRD},{ill,non,0    },{ill,non,0 },
  155.     {ill,non,0    },{ora,abx,MRD},{asl,abx,MRW},{ill,non,0 },
  156.     {jsr,adr,JMP},{and,idx,MRD},{ill,non,0    },{ill,non,0 },/* 20 */
  157.     {bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{ill,non,0 },
  158.     {plp,imp,0    },{and,imm,VAL},{rol,acc,0    },{ill,non,0 },
  159.     {bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{ill,non,0 },
  160.     {bmi,rel,BRA},{and,idy,MRD},{ill,non,0    },{ill,non,0 },/* 30 */
  161.     {ill,non,0    },{and,zpx,ZRD},{rol,zpx,ZRW},{ill,non,0 },
  162.     {sec,imp,0    },{and,aby,MRD},{ill,non,0    },{ill,non,0 },
  163.     {ill,non,0    },{and,abx,MRD},{rol,abx,MRW},{ill,non,0 },
  164.     {rti,imp,0    },{eor,idx,MRD},{ill,non,0    },{ill,non,0 },/* 40 */
  165.     {ill,non,0    },{eor,zpg,ZRD},{lsr,zpg,ZRW},{ill,non,0  },
  166.     {pha,imp,0    },{eor,imm,VAL},{lsr,acc,0    },{ill,non,0 },
  167.     {jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{ill,non,0 },
  168.     {bvc,rel,BRA},{eor,idy,MRD},{ill,non,0    },{ill,non,0 },/* 50 */
  169.     {ill,non,0    },{eor,zpx,ZRD},{lsr,zpx,ZRW},{ill,non,0 },
  170.     {cli,imp,0    },{eor,aby,MRD},{ill,non,0    },{ill,non,0 },
  171.     {ill,non,0    },{eor,abx,MRD},{lsr,abx,MRW},{ill,non,0 },
  172.     {rts,imp,0    },{adc,idx,MRD},{ill,non,0    },{ill,non,0 },/* 60 */
  173.     {ill,non,0    },{adc,zpg,ZRD},{ror,zpg,ZRW},{ill,non,0 },
  174.     {pla,imp,0    },{adc,imm,VAL},{ror,acc,0    },{ill,non,0 },
  175.     {jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{ill,non,0 },
  176.     {bvs,rel,BRA},{adc,idy,MRD},{ill,non,0    },{ill,non,0 },/* 70 */
  177.     {ill,non,0    },{adc,zpx,ZRD},{ror,zpx,ZRW},{ill,non,0 },
  178.     {sei,imp,0    },{adc,aby,MRD},{ill,non,0    },{ill,non,0 },
  179.     {ill,non,0    },{adc,abx,MRD},{ror,abx,MRW},{ill,non,0 },
  180.     {ill,non,0    },{sta,idx,MWR},{ill,non,0    },{ill,non,0 },/* 80 */
  181.     {sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{ill,non,0 },
  182.     {dey,imp,0    },{ill,non,0  },{txa,imp,0    },{ill,non,0 },
  183.     {sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{ill,non,0 },
  184.     {bcc,rel,BRA},{sta,idy,MWR},{ill,non,0    },{ill,non,0 },/* 90 */
  185.     {sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{ill,non,0 },
  186.     {tya,imp,0    },{sta,aby,MWR},{txs,imp,0    },{ill,non,0 },
  187.     {ill,non,0    },{sta,abx,MWR},{ill,non,0    },{ill,non,0 },
  188.     {ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
  189.     {ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{ill,non,0 },
  190.     {tay,imp,0    },{lda,imm,VAL},{tax,imp,0    },{ill,non,0 },
  191.     {ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{ill,non,0 },
  192.     {bcs,rel,BRA},{lda,idy,MRD},{ill,non,0    },{ill,non,0 },/* b0 */
  193.     {ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{ill,non,0 },
  194.     {clv,imp,0    },{lda,aby,MRD},{tsx,imp,0    },{ill,non,0 },
  195.     {ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{ill,non,0 },
  196.     {cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0    },{ill,non,0 },/* c0 */
  197.     {cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{ill,non,0 },
  198.     {iny,imp,0    },{cmp,imm,VAL},{dex,imp,0    },{ill,non,0 },
  199.     {cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{ill,non,0 },
  200.     {bne,rel,BRA},{cmp,idy,MRD},{ill,non,0    },{ill,non,0 },/* d0 */
  201.     {ill,non,0    },{cmp,zpx,ZRD},{dec,zpx,ZRW},{ill,non,0 },
  202.     {cld,imp,0    },{cmp,aby,MRD},{ill,non,0    },{ill,non,0 },
  203.     {ill,non,0    },{cmp,abx,MRD},{dec,abx,MRW},{ill,non,0 },
  204.     {cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0    },{ill,non,0 },/* e0 */
  205.     {cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{ill,non,0 },
  206.     {inx,imp,0    },{sbc,imm,VAL},{nop,imp,0    },{ill,non,0 },
  207.     {cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{ill,non,0 },
  208.     {beq,rel,BRA},{sbc,idy,MRD},{ill,non,0    },{ill,non,0 },/* f0 */
  209.     {ill,non,0    },{sbc,zpx,ZRD},{inc,zpx,ZRW},{ill,non,0 },
  210.     {sed,imp,0    },{sbc,aby,MRD},{ill,non,0    },{ill,non,0 },
  211.     {ill,non,0    },{sbc,abx,MRD},{inc,abx,MRW},{ill,non,0 }
  212. };
  213.  
  214. static const UINT8 op65c02[256][3] = {
  215.     {brk,imm,VAL},{ora,idx,MRD},{ill,non,0    },{ill,non,0 },/* 00 */
  216.     {tsb,zpg,0    },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
  217.     {php,imp,0    },{ora,imm,VAL},{asl,acc,MRW},{ill,non,0 },
  218.     {tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
  219.     {bpl,rel,BRA},{ora,idy,MRD},{ora,zpi,MRD},{ill,non,0 },/* 10 */
  220.     {trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
  221.     {clc,imp,0    },{ora,aby,MRD},{ina,imp,0    },{ill,non,0 },
  222.     {tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
  223.     {jsr,adr,0    },{and,idx,MRD},{ill,non,0    },{ill,non,0 },/* 20 */
  224.     {bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
  225.     {plp,imp,0    },{and,imm,VAL},{rol,acc,0    },{ill,non,0 },
  226.     {bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
  227.     {bmi,rel,BRA},{and,idy,MRD},{and,zpi,MRD},{ill,non,0 },/* 30 */
  228.     {bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
  229.     {sec,imp,0    },{and,aby,MRD},{dea,imp,0    },{ill,non,0 },
  230.     {bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
  231.     {rti,imp,0    },{eor,idx,MRD},{ill,non,0    },{ill,non,0 },/* 40 */
  232.     {ill,non,0    },{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
  233.     {pha,imp,0    },{eor,imm,VAL},{lsr,acc,0    },{ill,non,0 },
  234.     {jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
  235.     {bvc,rel,BRA},{eor,idy,MRD},{eor,zpi,MRD},{ill,non,0 },/* 50 */
  236.     {ill,non,0    },{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
  237.     {cli,imp,0    },{eor,aby,MRD},{phy,imp,0    },{ill,non,0 },
  238.     {ill,non,0    },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
  239.     {rts,imp,0    },{adc,idx,MRD},{ill,non,0    },{ill,non,0 },/* 60 */
  240.     {stz,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
  241.     {pla,imp,0    },{adc,imm,VAL},{ror,acc,0    },{ill,non,0 },
  242.     {jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
  243.     {bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{ill,non,0 },/* 70 */
  244.     {stz,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
  245.     {sei,imp,0    },{adc,aby,MRD},{ply,imp,0    },{ill,non,0 },
  246.     {jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
  247.     {bra,rel,BRA},{sta,idx,MWR},{ill,non,0    },{ill,non,0 },/* 80 */
  248.     {sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
  249.     {dey,imp,0    },{bit,imm,VAL},{txa,imp,0    },{ill,non,0 },
  250.     {sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
  251.     {bcc,rel,BRA},{sta,idy,MWR},{sta,zpi,MWR},{ill,non,0 },/* 90 */
  252.     {sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
  253.     {tya,imp,0    },{sta,aby,MWR},{txs,imp,0    },{ill,non,0 },
  254.     {stz,aba,MWR},{sta,abx,MWR},{stz,abx,MWR},{bbs,zpb,ZRD},
  255.     {ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
  256.     {ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
  257.     {tay,imp,0    },{lda,imm,VAL},{tax,imp,0    },{ill,non,0 },
  258.     {ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
  259.     {bcs,rel,BRA},{lda,idy,MRD},{lda,zpi,MRD},{ill,non,0 },/* b0 */
  260.     {ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
  261.     {clv,imp,0    },{lda,aby,MRD},{tsx,imp,0    },{ill,non,0 },
  262.     {ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
  263.     {cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0    },{ill,non,0 },/* c0 */
  264.     {cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
  265.     {iny,imp,0    },{cmp,imm,VAL},{dex,imp,0    },{ill,non,0 },
  266.     {cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
  267.     {bne,rel,BRA},{cmp,idy,MRD},{cmp,zpi,MRD},{ill,non,0 },/* d0 */
  268.     {ill,non,0    },{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
  269.     {cld,imp,0    },{cmp,aby,MRD},{phx,imp,0    },{ill,non,0 },
  270.     {ill,non,0    },{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
  271.     {cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0    },{ill,non,0 },/* e0 */
  272.     {cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
  273.     {inx,imp,0    },{sbc,imm,VAL},{nop,imp,0    },{ill,non,0 },
  274.     {cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
  275.     {beq,rel,BRA},{sbc,idy,MRD},{sbc,zpi,MRD},{ill,non,0 },/* f0 */
  276.     {ill,non,0    },{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
  277.     {sed,imp,0    },{sbc,aby,MRD},{plx,imp,0    },{ill,non,0 },
  278.     {ill,non,0    },{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
  279. };
  280.  
  281. /* only bsr additional to 65c02 yet */
  282. static const UINT8 op65sc02[256][3] = {
  283.     {brk,imm,VAL},{ora,idx,MRD},{ill,non,0    },{ill,non,0 },/* 00 */
  284.     {tsb,zpg,0    },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
  285.     {php,imp,0    },{ora,imm,VAL},{asl,acc,MRW},{ill,non,0 },
  286.     {tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
  287.     {bpl,rel,BRA},{ora,idy,MRD},{ora,zpi,MRD},{ill,non,0 },/* 10 */
  288.     {trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
  289.     {clc,imp,0    },{ora,aby,MRD},{ina,imp,0    },{ill,non,0 },
  290.     {tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
  291.     {jsr,adr,0    },{and,idx,MRD},{ill,non,0    },{ill,non,0 },/* 20 */
  292.     {bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
  293.     {plp,imp,0    },{and,imm,VAL},{rol,acc,0    },{ill,non,0 },
  294.     {bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
  295.     {bmi,rel,BRA},{and,idy,MRD},{and,zpi,MRD},{ill,non,0 },/* 30 */
  296.     {bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
  297.     {sec,imp,0    },{and,aby,MRD},{dea,imp,0    },{ill,non,0 },
  298.     {bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
  299.     {rti,imp,0    },{eor,idx,MRD},{ill,non,0    },{ill,non,0 },/* 40 */
  300.     {ill,non,0    },{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
  301.     {pha,imp,0    },{eor,imm,VAL},{lsr,acc,0    },{ill,non,0 },
  302.     {jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
  303.     {bvc,rel,BRA},{eor,idy,MRD},{eor,zpi,MRD},{ill,non,0 },/* 50 */
  304.     {ill,non,0    },{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
  305.     {cli,imp,0    },{eor,aby,MRD},{phy,imp,0    },{ill,non,0 },
  306.     {ill,non,0    },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
  307.     {rts,imp,0    },{adc,idx,MRD},{ill,non,0    },{bsr,rw2,BRA},/* 60 */
  308.     {stz,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
  309.     {pla,imp,0    },{adc,imm,VAL},{ror,acc,0    },{ill,non,0 },
  310.     {jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
  311.     {bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{ill,non,0 },/* 70 */
  312.     {stz,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
  313.     {sei,imp,0    },{adc,aby,MRD},{ply,imp,0    },{ill,non,0 },
  314.     {jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
  315.     {bra,rel,BRA},{sta,idx,MWR},{ill,non,0    },{ill,non,0 },/* 80 */
  316.     {sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
  317.     {dey,imp,0    },{bit,imm,VAL},{txa,imp,0    },{ill,non,0 },
  318.     {sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
  319.     {bcc,rel,BRA},{sta,idy,MWR},{sta,zpi,MWR},{ill,non,0 },/* 90 */
  320.     {sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
  321.     {tya,imp,0    },{sta,aby,MWR},{txs,imp,0    },{ill,non,0 },
  322.     {stz,aba,MWR},{sta,abx,MWR},{stz,abx,MWR},{bbs,zpb,ZRD},
  323.     {ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
  324.     {ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
  325.     {tay,imp,0    },{lda,imm,VAL},{tax,imp,0    },{ill,non,0 },
  326.     {ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
  327.     {bcs,rel,BRA},{lda,idy,MRD},{lda,zpi,MRD},{ill,non,0 },/* b0 */
  328.     {ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
  329.     {clv,imp,0    },{lda,aby,MRD},{tsx,imp,0    },{ill,non,0 },
  330.     {ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
  331.     {cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0    },{ill,non,0 },/* c0 */
  332.     {cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
  333.     {iny,imp,0    },{cmp,imm,VAL},{dex,imp,0    },{ill,non,0 },
  334.     {cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
  335.     {bne,rel,BRA},{cmp,idy,MRD},{cmp,zpi,MRD},{ill,non,0 },/* d0 */
  336.     {ill,non,0    },{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
  337.     {cld,imp,0    },{cmp,aby,MRD},{phx,imp,0    },{ill,non,0 },
  338.     {ill,non,0    },{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
  339.     {cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0    },{ill,non,0 },/* e0 */
  340.     {cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
  341.     {inx,imp,0    },{sbc,imm,VAL},{nop,imp,0    },{ill,non,0 },
  342.     {cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
  343.     {beq,rel,BRA},{sbc,idy,MRD},{sbc,zpi,MRD},{ill,non,0 },/* f0 */
  344.     {ill,non,0    },{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
  345.     {sed,imp,0    },{sbc,aby,MRD},{plx,imp,0    },{ill,non,0 },
  346.     {ill,non,0    },{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
  347. };
  348.  
  349. static const UINT8 op6510[256][3] = {
  350.     {brk,imm,VAL},{ora,idx,MRD},{kil,non,0    },{slo,idx,MRW},/* 00 */
  351.     {dop,imm,VAL},{ora,zpg,ZRD},{asl,zpg,ZRW},{slo,zpg,ZRW},
  352.     {php,imp,0    },{ora,imm,VAL},{asl,acc,0    },{anc,imm,VAL},
  353.     {top,iw2,VAL},{ora,aba,MRD},{asl,aba,MRW},{slo,aba,MRW},
  354.     {bpl,rel,BRA},{ora,idy,MRD},{nop,imp,0    },{slo,idy,MRW},/* 10 */
  355.     {dop,imm,VAL},{ora,zpx,ZRD},{asl,zpx,ZRW},{slo,zpx,ZRW},
  356.     {clc,imp,0    },{ora,aby,MRD},{kil,non,0    },{slo,aby,MRW},
  357.     {top,iw2,VAL},{ora,abx,MRD},{asl,abx,MRW},{slo,abx,MRW},
  358.     {jsr,adr,JMP},{and,idx,MRD},{kil,non,0    },{rla,idx,MRW},/* 20 */
  359.     {bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rla,zpg,ZRW},
  360.     {plp,imp,0    },{and,imm,VAL},{rol,acc,0    },{anc,imm,VAL},
  361.     {bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{rla,aba,MRW},
  362.     {bmi,rel,BRA},{and,idy,MRD},{kil,non,0    },{rla,idy,MRW},/* 30 */
  363.     {dop,imm,VAL},{and,zpx,ZRD},{rol,zpx,ZRW},{rla,zpx,ZRW},
  364.     {sec,imp,0    },{and,aby,MRD},{nop,imp,0    },{rla,aby,MRW},
  365.     {top,iw2,VAL},{and,abx,MRD},{rol,abx,MRW},{rla,abx,MRW},
  366.     {rti,imp,0    },{eor,idx,MRD},{kil,non,0    },{sre,idx,MRW},/* 40 */
  367.     {dop,imm,VAL},{eor,zpg,ZRD},{lsr,zpg,ZRW},{sre,zpg,ZRW},
  368.     {pha,imp,0    },{eor,imm,VAL},{lsr,acc,0    },{asr,imm,VAL},
  369.     {jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{sre,aba,MRW},
  370.     {bvc,rel,BRA},{eor,idy,MRD},{kil,non,0    },{sre,idy,MRW},/* 50 */
  371.     {dop,imm,VAL},{eor,zpx,ZRD},{lsr,zpx,ZRW},{sre,zpx,ZRW},
  372.     {cli,imp,0    },{eor,aby,MRD},{nop,imp,0    },{sre,aby,MRW},
  373.     {top,iw2,VAL},{eor,abx,MRD},{lsr,abx,MRW},{sre,abx,MRW},
  374.     {rts,imp,0    },{adc,idx,MRD},{kil,non,0    },{rra,idx,MRW},/* 60 */
  375.     {dop,imm,VAL},{adc,zpg,ZRD},{ror,zpg,ZRW},{rra,zpg,ZRW},
  376.     {pla,imp,0    },{adc,imm,VAL},{ror,acc,0    },{arr,imm,VAL},
  377.     {jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{rra,aba,MRW},
  378.     {bvs,rel,BRA},{adc,idy,MRD},{kil,non,0    },{rra,idy,MRW},/* 70 */
  379.     {dop,imm,VAL},{adc,zpx,ZRD},{ror,zpx,ZRW},{rra,zpx,ZRW},
  380.     {sei,imp,0    },{adc,aby,MRD},{nop,imp,0    },{rra,aby,MRW},
  381.     {top,iw2,VAL},{adc,abx,MRD},{ror,abx,MRW},{rra,abx,MRW},
  382.     {dop,imm,VAL},{sta,idx,MWR},{dop,imm,VAL},{sax,idx,MWR},/* 80 */
  383.     {sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{sax,zpg,ZWR},
  384.     {dey,imp,0    },{dop,imm,VAL},{txa,imp,0  },{axa,imm,VAL},
  385.     {sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{sax,aba,MWR},
  386.     {bcc,rel,BRA},{sta,idy,MWR},{kil,non,0    },{say,idy,MWR},/* 90 */
  387.     {sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{sax,zpx,ZWR},
  388.     {tya,imp,0    },{sta,aby,MWR},{txs,imp,0    },{ssh,aby,MWR},
  389.     {syh,abx,0    },{sta,abx,MWR},{sxh,aby,MWR},{sah,aby,MWR},
  390.     {ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{lax,idx,MRD},/* a0 */
  391.     {ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{lax,zpg,ZRD},
  392.     {tay,imp,0    },{lda,imm,VAL},{tax,imp,0    },{oal,imm,VAL},
  393.     {ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{lax,aba,MRD},
  394.     {bcs,rel,BRA},{lda,idy,MRD},{kil,non,0    },{lax,idy,MRD},/* b0 */
  395.     {ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{lax,zpx,ZRD},
  396.     {clv,imp,0    },{lda,aby,MRD},{tsx,imp,0    },{ast,aby,MRD},
  397.     {ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{lax,abx,MRD},
  398.     {cpy,imm,VAL},{cmp,idx,MRD},{dop,imm,VAL},{dcp,idx,MRW},/* c0 */
  399.     {cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{dcp,zpg,ZRW},
  400.     {iny,imp,0    },{cmp,imm,VAL},{dex,imp,0    },{asx,imm,VAL},
  401.     {cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{dcp,aba,MRW},
  402.     {bne,rel,BRA},{cmp,idy,MRD},{kil,non,0    },{dcp,idy,MRW},/* d0 */
  403.     {dop,imm,VAL},{cmp,zpx,ZRD},{dec,zpx,ZRW},{dcp,zpx,ZRW},
  404.     {cld,imp,0    },{cmp,aby,MRD},{nop,imp,0    },{dcp,aby,MRW},
  405.     {top,iw2,VAL},{cmp,abx,MRD},{dec,abx,MRW},{dcp,abx,MRW},
  406.     {cpx,imm,VAL},{sbc,idx,MRD},{dop,imm,VAL},{isc,idx,MRW},/* e0 */
  407.     {cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{isc,zpg,ZRW},
  408.     {inx,imp,0    },{sbc,imm,VAL},{nop,imp,0    },{sbc,imm,VAL},
  409.     {cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{isc,aba,MRW},
  410.     {beq,rel,BRA},{sbc,idy,MRD},{kil,non,0    },{isc,idy,MRW},/* f0 */
  411.     {dop,imm,VAL},{sbc,zpx,ZRD},{inc,zpx,ZRW},{isc,zpx,ZRW},
  412.     {sed,imp,0    },{sbc,aby,MRD},{nop,imp,0    },{isc,aby,MRW},
  413.     {top,iw2,VAL},{sbc,abx,MRD},{inc,abx,MRW},{isc,abx,MRW}
  414. };
  415.  
  416. #if (HAS_M65CE02)
  417. static const UINT8 op65ce02[256][3] = {
  418.     {brk,imm,VAL},{ora,idx,MRD},{cle,imp,0    },{see,imp,0  },/* 00 */
  419.     {tsb,zpg,0    },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
  420.     {php,imp,0    },{ora,imm,VAL},{asl,acc,MRW},{tsy,imp,0  },
  421.     {tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
  422.     {bpl,rel,BRA},{ora,idy,MRD},{ora,idz,MRD},{bpl,rw2,BRA},/* 10 */
  423.     {trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
  424.     {clc,imp,0    },{ora,aby,MRD},{ina,imp,0    },{inz,imp,0  },
  425.     {tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
  426.     {jsr,adr,0    },{and,idx,MRD},{jsr,ind,0    },{jsr,iax,0  },/* 20 */
  427.     {bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
  428.     {plp,imp,0    },{and,imm,VAL},{rol,acc,0    },{tys,imp,0  },
  429.     {bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
  430.     {bmi,rel,BRA},{and,idz,MRD},{and,zpi,MRD},{bmi,rw2,BRA},/* 30 */
  431.     {bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
  432.     {sec,imp,0    },{and,aby,MRD},{dea,imp,0    },{dez,imp,0  },
  433.     {bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
  434.     {rti,imp,0    },{eor,idx,MRD},{neg,imp,0    },{asr2,imp,0 },/* 40 */
  435.     {asr2,zpg,ZRW},{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
  436.     {pha,imp,0    },{eor,imm,VAL},{lsr,acc,0    },{taz,imp,0  },
  437.     {jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
  438.     {bvc,rel,BRA},{eor,idy,MRD},{eor,idz,MRD},{bvc,rw2,BRA},/* 50 */
  439.     {asr2,zpx,ZRW},{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
  440.     {cli,imp,0    },{eor,aby,MRD},{phy,imp,0    },{tab,imp,0  },
  441.     {map,imp,0    },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
  442.     {rts,imp,0    },{adc,idx,MRD},{rts,imm,VAL},{bsr,rw2,BRA},/* 60 */
  443.     {stz2,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
  444.     {pla,imp,0    },{adc,imm,VAL},{ror,acc,0    },{tza,imp,0  },
  445.     {jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
  446.     {bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{bvs,rw2,BRA},/* 70 */
  447.     {stz2,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
  448.     {sei,imp,0    },{adc,aby,MRD},{ply,imp,0    },{tba,imp,0  },
  449.     {jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
  450.     {bra,rel,BRA},{sta,idx,MWR},{sta,isy,MWR},{bra,rw2,BRA},/* 80 */
  451.     {sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
  452.     {dey,imp,0    },{bit,imm,VAL},{txa,imp,0    },{sty,abx,MWR},
  453.     {sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
  454.     {bcc,rel,BRA},{sta,idy,MWR},{sta,inz,MWR},{bcc,rw2,BRA},/* 90 */
  455.     {sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
  456.     {tya,imp,0    },{sta,aby,MWR},{txs,imp,0    },{stx,aby,MWR},
  457.     {stz2,aba,MWR},{sta,abx,MWR},{stz2,abx,MWR},{bbs,zpb,ZRD},
  458.     {ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ldz,imm,VAL},/* a0 */
  459.     {ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
  460.     {tay,imp,0    },{lda,imm,VAL},{tax,imp,0    },{ldz,aba,MRD},
  461.     {ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
  462.     {bcs,rel,BRA},{lda,idy,MRD},{lda,inz,MRD},{bcs,rw2,BRA},/* b0 */
  463.     {ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
  464.     {clv,imp,0    },{lda,aby,MRD},{tsx,imp,0    },{ldz,abx,MRD},
  465.     {ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
  466.     {cpy,imm,VAL},{cmp,idx,MRD},{cpz,imm,VAL},{dew,zpg,ZRW2},/* c0 */
  467.     {cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
  468.     {iny,imp,0    },{cmp,imm,VAL},{dex,imp,0    },{asw,aba,MRW2},
  469.     {cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
  470.     {bne,rel,BRA},{cmp,idy,MRD},{cmp,idz,MRD},{bne,rw2,BRA},/* d0 */
  471.     {cpz,zpg,MRD},{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
  472.     {cld,imp,0    },{cmp,aby,MRD},{phx,imp,0    },{phz,imp,0  },
  473.     {cpz,aba,MRD},{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
  474.     {cpx,imm,VAL},{sbc,idx,MRD},{lda,isy,MRD},{inw,zpg,ZRW2},/* e0 */
  475.     {cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
  476.     {inx,imp,0    },{sbc,imm,VAL},{nop,imp,0    },{row,aba,MRW2},
  477.     {cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
  478.     {beq,rel,BRA},{sbc,idy,MRD},{sbc,idz,MRD},{beq,rw2,BRA},/* f0 */
  479.     {phw,iw2,VAL},{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
  480.     {sed,imp,0    },{sbc,aby,MRD},{plx,imp,0    },{plz,imp,0  },
  481.     {phw,aba,MRD2},{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
  482. };
  483. #endif
  484.  
  485. /*****************************************************************************
  486.  * Disassemble a single opcode starting at pc
  487.  *****************************************************************************/
  488. unsigned Dasm6502(char *buffer, unsigned pc)
  489. {
  490.     char *dst = buffer;
  491.     const char *symbol;
  492.     INT8 offset;
  493.     INT16 offset16;
  494.     unsigned PC = pc;
  495.     UINT16 addr, ea;
  496.     UINT8 op, opc, arg, access, value;
  497.  
  498.     op = OPCODE(pc++);
  499.  
  500.     switch ( m6502_get_reg(M6502_SUBTYPE) )
  501.     {
  502. #if (HAS_M65C02)
  503.         case SUBTYPE_65C02:
  504.             opc = op65c02[op][0];
  505.             arg = op65c02[op][1];
  506.             access = op65c02[op][2];
  507.             break;
  508. #endif
  509. #if (HAS_M65SC02)
  510.         case SUBTYPE_65SC02:
  511.             opc = op65sc02[op][0];
  512.             arg = op65sc02[op][1];
  513.             access = op65sc02[op][2];
  514.             break;
  515. #endif
  516. #if (HAS_M6510)
  517.         case SUBTYPE_6510:
  518.             opc = op6510[op][0];
  519.             arg = op6510[op][1];
  520.             access = op6510[op][2];
  521.             break;
  522. #endif
  523.         default:
  524.             opc = op6502[op][0];
  525.             arg = op6502[op][1];
  526.             access = op6502[op][2];
  527.             break;
  528.     }
  529.     dst += sprintf(dst, "%-5s", token[opc]);
  530.     if( opc == bbr || opc == bbs || opc == rmb || opc == smb )
  531.         dst += sprintf(dst, "%d,", (op >> 3) & 7);
  532.  
  533.     switch(arg)
  534.     {
  535.     case imp:
  536.         break;
  537.  
  538.     case acc:
  539.         dst += sprintf(dst,"a");
  540.         break;
  541.  
  542.     case rel:
  543.         offset = (INT8)ARGBYTE(pc++);
  544.         symbol = set_ea_info( 0, pc, offset, access );
  545.         dst += sprintf(dst,"%s", symbol);
  546.         break;
  547.  
  548.     case rw2:
  549.         offset16 = ARGWORD(pc)-1;
  550.         pc += 2;
  551.         symbol = set_ea_info( 0, pc, offset16, access );
  552.         dst += sprintf(dst,"%s", symbol);
  553.         break;
  554.  
  555.     case imm:
  556.         value = ARGBYTE(pc++);
  557.         symbol = set_ea_info( 0, value, EA_UINT8, access );
  558.         dst += sprintf(dst,"#%s", symbol);
  559.         break;
  560.  
  561.     case zpg:
  562.         addr = ARGBYTE(pc++);
  563.         symbol = set_ea_info( 0, addr, EA_UINT8, access );
  564.         dst += sprintf(dst,"$%02X", addr);
  565.         break;
  566.  
  567.     case zpx:
  568.         addr = ARGBYTE(pc++);
  569.         ea = (addr + m6502_get_reg(M6502_X)) & 0xff;
  570.         symbol = set_ea_info( 0, ea, EA_UINT8, access );
  571.         dst += sprintf(dst,"$%02X,x", addr);
  572.         break;
  573.  
  574.     case zpy:
  575.         addr = ARGBYTE(pc++);
  576.         ea = (addr + m6502_get_reg(M6502_Y)) & 0xff;
  577.         symbol = set_ea_info( 0, ea, EA_UINT8, access );
  578.         dst += sprintf(dst,"$%02X,y", addr);
  579.         break;
  580.  
  581.     case idx:
  582.         addr = ARGBYTE(pc++);
  583.         ea = (addr + m6502_get_reg(M6502_X)) & 0xff;
  584.         ea = RDMEM(ea) + (RDMEM((ea+1) & 0xff) << 8);
  585.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  586.         dst += sprintf(dst,"($%02X,x)", addr);
  587.         break;
  588.  
  589.     case idy:
  590.         addr = ARGBYTE(pc++);
  591.         ea = (RDMEM(addr) + (RDMEM((addr+1) & 0xff) << 8) + m6502_get_reg(M6502_Y)) & 0xffff;
  592.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  593.         dst += sprintf(dst,"($%02X),y", addr);
  594.         break;
  595.  
  596.     case zpi:
  597.         addr = ARGBYTE(pc++);
  598.         ea = RDMEM(addr) + (RDMEM((addr+1) & 0xff) << 8);
  599.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  600.         dst += sprintf(dst,"($%02X)", addr);
  601.         break;
  602.  
  603.     case zpb:
  604.         addr = ARGBYTE(pc++);
  605.         symbol = set_ea_info( 0, addr, EA_UINT8, access );
  606.         dst += sprintf(dst,"$%02X", addr);
  607.         offset = (INT8)ARGBYTE(pc++);
  608.         symbol = set_ea_info( 1, pc, offset, BRA );
  609.         dst += sprintf(dst,",%s", symbol);
  610.         break;
  611.  
  612.     case adr:
  613.         addr = ARGWORD(pc);
  614.         pc += 2;
  615.         symbol = set_ea_info( 0, addr, EA_UINT16, access );
  616.         dst += sprintf(dst,"%s", symbol);
  617.         break;
  618.  
  619.     case aba:
  620.         addr = ARGWORD(pc);
  621.         pc += 2;
  622.         symbol = set_ea_info( 0, addr, EA_UINT16, access );
  623.         dst += sprintf(dst,"%s", symbol);
  624.         break;
  625.  
  626.     case abx:
  627.         addr = ARGWORD(pc);
  628.         pc += 2;
  629.         ea = (addr + m6502_get_reg(M6502_X)) & 0xffff;
  630.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  631.         dst += sprintf(dst,"$%04X,x", addr);
  632.         break;
  633.  
  634.     case aby:
  635.         addr = ARGWORD(pc);
  636.         pc += 2;
  637.         ea = (addr + m6502_get_reg(M6502_Y)) & 0xffff;
  638.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  639.         dst += sprintf(dst,"$%04X,y", addr);
  640.         break;
  641.  
  642.     case ind:
  643.         addr = ARGWORD(pc);
  644.         pc += 2;
  645.         ea = ARGWORD(addr);
  646.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  647.         dst += sprintf(dst,"($%04X)", addr);
  648.         break;
  649.  
  650.     case iax:
  651.         addr = ARGWORD(pc);
  652.         pc += 2;
  653.         ea = (ARGWORD(addr) + m6502_get_reg(M6502_X)) & 0xffff;
  654.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  655.         dst += sprintf(dst,"($%04X),X", addr);
  656.         break;
  657.  
  658.     default:
  659.         dst += sprintf(dst,"$%02X", op);
  660.     }
  661.     return pc - PC;
  662. }
  663.  
  664.  
  665. #if (HAS_M65CE02 || HAS_M6509 || HAS_M6510 || HAS_M4510)
  666.  
  667. #if (HAS_65CE02 || HAS_M6510)
  668. static int m6502_get_argword(int addr)
  669. {
  670.     return cpu_readop_arg(addr)+(cpu_readop_arg((addr+1)&0xffff) << 8);
  671. }
  672. #endif
  673.  
  674. #if (HAS_M6509 || HAS_M4510)
  675. static int m6509_get_argword(int addr)
  676. {
  677.     if ((addr&0xffff)==0xffff)
  678.         return cpu_readop_arg(addr)+(cpu_readop_arg(addr&~0xffff) << 8);
  679.     else
  680.         return cpu_readop_arg(addr)+(cpu_readop_arg(addr+1) << 8);
  681. }
  682. #endif
  683.  
  684. typedef struct {
  685.     const UINT8 *opcode;
  686.     unsigned(*get_reg)(int regnum);
  687.     mem_read_handler readmem;
  688.     int(*argword)(int addr);
  689. } CPU_TYPE;
  690.  
  691. #if 0
  692. static CPU_TYPE type_m6502 = {
  693.     (const UINT8*)op6502, m6502_get_reg, cpu_readmem16, m6502_get_argword
  694. };
  695. #endif
  696. #ifdef HAS_M6510
  697. static CPU_TYPE type_m6510 = {
  698.     (const UINT8*)op6510, m6502_get_reg, cpu_readmem16, m6502_get_argword
  699. };
  700. #endif
  701. #if (HAS_M6509)
  702. static CPU_TYPE type_m6509 = {
  703.     (const UINT8*)op6510, m6509_get_reg, cpu_readmem20, m6509_get_argword
  704. };
  705. #endif
  706. #if 0
  707. static CPU_TYPE type_m65c02 = {
  708.     (const UINT8*)op65c02, m6502_get_reg, cpu_readmem16, m6502_get_argword
  709. };
  710. static CPU_TYPE type_m65sc02 = {
  711.     (const UINT8*)op65sc02, m6502_get_reg, cpu_readmem16, m6502_get_argword
  712. };
  713. #endif
  714. #if (HAS_M65CE02)
  715. static CPU_TYPE type_m65ce02 = {
  716.     (const UINT8*)op65ce02, m65ce02_get_reg, cpu_readmem16, m6502_get_argword
  717. };
  718. #endif
  719. #if (HAS_M4510)
  720. static READ_HANDLER(m4510_readmem)
  721. {
  722.     return cpu_readmem20( m4510_get_reg(M4510_MEM0+(offset>>13))+offset );
  723. }
  724.  
  725. static CPU_TYPE type_m4510 = {
  726.     (const UINT8*)op65ce02, m4510_get_reg, m4510_readmem, m6509_get_argword
  727. };
  728. #endif
  729.  
  730. /*****************************************************************************
  731.  * Disassemble a single opcode starting at pc
  732.  *****************************************************************************/
  733. unsigned int Dasm6502Helper(CPU_TYPE *this, char *buffer, unsigned pc)
  734. {
  735.     char *dst = buffer;
  736.     const char *symbol;
  737.     INT8 offset;
  738.     INT16 offset16;
  739.     unsigned PC = pc;
  740.     UINT16 addr, ea;
  741.     UINT8 op, opc, arg, access, value;
  742.  
  743.     op = OPCODE(pc++);
  744.  
  745.     opc = this->opcode[op*3];
  746.     arg = this->opcode[op*3+1];
  747.     access = this->opcode[op*3+2];
  748.  
  749.     dst += sprintf(dst, "%-5s", token[opc]);
  750.     if( opc == bbr || opc == bbs || opc == rmb || opc == smb )
  751.         dst += sprintf(dst, "%d,", (op >> 3) & 7);
  752.  
  753.     switch(arg)
  754.     {
  755.     case imp:
  756.         break;
  757.  
  758.     case acc:
  759.         dst += sprintf(dst,"a");
  760.         break;
  761.  
  762.     case rel:
  763.         offset = (INT8)ARGBYTE(pc++);
  764.         symbol = set_ea_info( 0, pc, offset, access );
  765. #if 0
  766.         dst += sprintf(dst,"%s", symbol);
  767. #else
  768.         dst += sprintf(dst,"$%04X", (pc+offset)&0xffff);
  769. #endif
  770.         break;
  771.  
  772.     case rw2:
  773.         offset16 = this->argword(pc)-1;
  774.         pc += 2;
  775.         symbol = set_ea_info( 0, pc, offset16, access );
  776. #if 0
  777.         dst += sprintf(dst,"%s", symbol);
  778. #else
  779.         dst += sprintf(dst,"$%04X", (pc+offset16)&0xffff );
  780. #endif
  781.         break;
  782.  
  783.     case imm:
  784.         value = ARGBYTE(pc++);
  785.         symbol = set_ea_info( 0, value, EA_UINT8, access );
  786.         dst += sprintf(dst,"#%s", symbol);
  787.         break;
  788.  
  789.     case iw2:
  790.         addr = ARGWORD(pc);
  791.         pc += 2;
  792.         symbol = set_ea_info( 0, addr, EA_UINT16, access );
  793.         dst += sprintf(dst,"#%s", symbol);
  794.         break;
  795.  
  796.     case zpg:
  797.         addr = ARGBYTE(pc++);
  798.         symbol = set_ea_info( 0, addr, EA_UINT8, access );
  799.         dst += sprintf(dst,"$%02X", addr);
  800.         break;
  801.  
  802.     case zpx:
  803.         addr = ARGBYTE(pc++);
  804.         ea = (addr + this->get_reg(M6502_X)) & 0xff;
  805.         symbol = set_ea_info( 0, ea, EA_UINT8, access );
  806.         dst += sprintf(dst,"$%02X,x", addr);
  807.         break;
  808.  
  809.     case zpy:
  810.         addr = ARGBYTE(pc++);
  811.         ea = (addr + this->get_reg(M6502_Y)) & 0xff;
  812.         symbol = set_ea_info( 0, ea, EA_UINT8, access );
  813.         dst += sprintf(dst,"$%02X,y", addr);
  814.         break;
  815.  
  816.     case idx:
  817.         addr = ARGBYTE(pc++);
  818.         ea = (addr + this->get_reg(M6502_X)) & 0xff;
  819.         ea = this->readmem(ea) + (this->readmem((ea+1) & 0xff) << 8);
  820.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  821.         dst += sprintf(dst,"($%02X,x)", addr);
  822.         break;
  823.  
  824.     case idy:
  825.         addr = ARGBYTE(pc++);
  826.         ea = (this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8)
  827.               + this->get_reg(M6502_Y)) & 0xffff;
  828.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  829.         dst += sprintf(dst,"($%02X),y", addr);
  830.         break;
  831.  
  832.     case idz:
  833.         addr = ARGBYTE(pc++);
  834.         ea = (this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8)
  835.               + this->get_reg(M6502_Y)) & 0xffff;
  836.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  837.         dst += sprintf(dst,"($%02X),z", addr);
  838.         break;
  839.  
  840.     case isy:
  841.         op = ARGBYTE(pc++);
  842.         addr = op+this->get_reg(M6502_S);
  843.         ea = (this->readmem(addr)+(this->readmem(addr+1) << 8)+
  844.                this->get_reg(M6502_Y)) & 0xffff;
  845.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  846.         dst += sprintf(dst,"(s,$%02X),y", addr);
  847.         break;
  848.  
  849.     case zpi:
  850.         addr = ARGBYTE(pc++);
  851.         ea = this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8);
  852.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  853.         dst += sprintf(dst,"($%02X)", addr);
  854.         break;
  855.  
  856.     case zpb:
  857.         addr = ARGBYTE(pc++);
  858.         symbol = set_ea_info( 0, addr, EA_UINT8, access );
  859.         dst += sprintf(dst,"$%02X", addr);
  860.         offset = (INT8)ARGBYTE(pc++);
  861.         symbol = set_ea_info( 1, pc, offset, BRA );
  862.         dst += sprintf(dst,",%s", symbol);
  863.         break;
  864.  
  865.     case adr:
  866.         addr = this->argword(pc);
  867.         pc += 2;
  868.         symbol = set_ea_info( 0, addr, EA_UINT16, access );
  869. #if 0
  870.         dst += sprintf(dst,"%s", symbol);
  871. #else
  872.         dst += sprintf(dst, "$%04X", addr);
  873. #endif
  874.         break;
  875.  
  876.     case aba:
  877.         addr = this->argword(pc);
  878.         pc += 2;
  879.         symbol = set_ea_info( 0, addr, EA_UINT16, access );
  880. #if 0
  881.         dst += sprintf(dst,"%s", symbol);
  882. #else
  883.         dst += sprintf(dst, "$%04X", addr);
  884. #endif
  885.         break;
  886.  
  887.     case abx:
  888.         addr = this->argword(pc);
  889.         pc += 2;
  890.         ea = (addr + this->get_reg(M6502_X)) & 0xffff;
  891.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  892.         dst += sprintf(dst,"$%04X,x", addr);
  893.         break;
  894.  
  895.     case aby:
  896.         addr = this->argword(pc);
  897.         pc += 2;
  898.         ea = (addr + this->get_reg(M6502_Y)) & 0xffff;
  899.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  900.         dst += sprintf(dst,"$%04X,y", addr);
  901.         break;
  902.  
  903.     case ind:
  904.         addr = this->argword(pc);
  905.         pc += 2;
  906.         ea = this->argword(addr);
  907.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  908.         dst += sprintf(dst,"($%04X)", addr);
  909.         break;
  910.  
  911.     case iax:
  912.         addr = this->argword(pc);
  913.         pc += 2;
  914.         ea = (this->argword(addr) + this->get_reg(M6502_X)) & 0xffff;
  915.         symbol = set_ea_info( 0, ea, EA_UINT16, access );
  916.         dst += sprintf(dst,"($%04X),X", addr);
  917.         break;
  918.  
  919.     default:
  920.         dst += sprintf(dst,"$%02X", op);
  921.     }
  922.     return pc - PC;
  923. }
  924. #endif
  925.  
  926. #if (HAS_M65CE02)
  927. /*****************************************************************************
  928.  * Disassemble a single opcode starting at pc
  929.  *****************************************************************************/
  930. unsigned int Dasm65ce02(char *buffer, unsigned pc)
  931. {
  932.     return Dasm6502Helper(&type_m65ce02, buffer, pc);
  933. }
  934. #endif
  935.  
  936. #if (HAS_M6509)
  937. /*****************************************************************************
  938.  * Disassemble a single opcode starting at pc
  939.  *****************************************************************************/
  940. unsigned int Dasm6509(char *buffer, unsigned pc)
  941. {
  942.     return Dasm6502Helper(&type_m6509, buffer, pc);
  943. }
  944. #endif
  945.  
  946. #if (HAS_M6510)
  947. /*****************************************************************************
  948.  * Disassemble a single opcode starting at pc
  949.  *****************************************************************************/
  950. unsigned int Dasm6510(char *buffer, unsigned pc)
  951. {
  952.     return Dasm6502Helper(&type_m6510, buffer, pc);
  953. }
  954. #endif
  955.  
  956. #if (HAS_M4510)
  957. /*****************************************************************************
  958.  * Disassemble a single opcode starting at pc
  959.  *****************************************************************************/
  960. unsigned int Dasm4510(char *buffer, unsigned pc)
  961. {
  962.     return Dasm6502Helper(&type_m4510, buffer, pc);
  963. }
  964. #endif
  965.  
  966. #endif    /* MAME_DEBUG */
  967.  
  968.  
  969.